package com.xxx.routing;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;

/**
 * Rabbit MQ使用场景四：根据路由key订阅消息
 * 
 * @author guweiqiang
 * 2018年6月13日
 */
public class RoutingReceiver1 {

//	private static final String HOST = "localhost";
	private static final String EXCHANGE_NAME = "amq.direct";
	// 路由关键字，只订阅info关键字的消息
    private static final String[] ROUTING_KEYS = new String[]{"info", "warning"};
    
	public static void main(String[] args) throws IOException, TimeoutException {
		// 1.创建连接工厂，并设置工厂相关属性
		ConnectionFactory factory = new ConnectionFactory();
//		factory.setHost(HOST); // 默认为localhost
		
		// 2.创建一个连接
		Connection connection = factory.newConnection();
		
		// 3.创建一个通道
		Channel channel = connection.createChannel();

		// 4.声明交换机
		channel.exchangeDeclare(EXCHANGE_NAME, "direct", true); // 交换机类型为：direct
		// direct 直接交换器，工作方式类似于单播，Exchange会将消息发送完全匹配ROUTING_KEY的Queue
		
		// 5.获取匿名队列名称（没有指定queue名称）
		String queueName = channel.queueDeclare().getQueue();
		
		// 6.根据路由关键字进行绑定
		for (String routingKey : ROUTING_KEYS) {
			// 将队列绑定到对应的exchanger上，每个queue可以绑定多个exchanger（相当于订阅了多个）
			channel.queueBind(queueName, EXCHANGE_NAME, routingKey);
			channel.basicQos(1); // 同一时刻服务器只会发一条消息给消费者
			System.out.println("RoutingReceiver1 queueName:" + queueName 
					+ " exchange:" + EXCHANGE_NAME + " routingKey:" + routingKey);
		}
		
		System.out.println("RoutingReceiver1 waiting for message:");
		// 7.消费消息
		Consumer consumer = new DefaultConsumer(channel) {
			@Override
			public void handleDelivery(String consumerTag,
										Envelope envelope,
										AMQP.BasicProperties properties,
										byte[] body) {
				String message = new String(body);
				System.out.println("RoutingReceiver1 received message: " + message);
			}
		};
		
		// 8.消费消息之后回复生产者（批量消费消息后1次性回复）
		channel.basicConsume(queueName, true, consumer);
	}

}
